#pragma once
#include <MsHTML.h>
#include <vector>
#include <map>
#include "DOMTreeDivider.h"
//#include <hash_map>

/**********************************************************
  * Date: 2005-10-31
  * Author: jzhang
  * Purpose: a wrapper class for IHTMLDOMNode
  *
  * Copyright FRDC
**********************************************************/
class DOMNode
{
	friend class DOMTreeDivider;
	friend class MyDOMTree;

//-------------------------------
// for display a box in the web page
public:
	void ShowRect();
	void RestoreRect();
private:
	bool m_bShowed;
	CComBSTR m_strOldBorder;
//------------------------------

public:
	DOMNode(void):m_nTextLength(0),m_nLinkNum(0),m_bShowed(false){};
	DOMNode(IHTMLElement* pElem):m_pDOMNode(pElem),m_nTextLength(0),m_nLinkNum(0),m_bShowed(false)
	{GetElementInfo();GetAttrInfo();GetVisualInfo();GetCurrentStyleText();};
	DOMNode(IHTMLDOMNode* pElem):m_pDOMNode(pElem),m_nTextLength(0),m_nLinkNum(0),m_bShowed(false)
	{GetElementInfo();GetAttrInfo();GetVisualInfo();GetCurrentStyleText();};
	~DOMNode(void){
		for(std::vector<DOMNode*>::iterator i=m_Children.begin();i!=m_Children.end();i++){
			delete (*i);
		}
	};
	enum {
		ELEMENT_TYPE = 1,
		TEXT_TYPE = 3
	};
	enum {
		NON_VALID_NODE=0,// a node that can not be seen through the browser
		VALID_NODE = 1, // a node that can be seen throgh the browser
	};
	enum {
		INLINE_NODE=1, // a node with inline text tags
		LINE_BREAK_NODE=2 // the node with tag other than inline text tags
	};

	const CString& GetTagName(){return m_TagName;};
	// root last tree calculating for node type and text and text/link, and other info
	void CalcTreeInfo();
	//is this node dividable
	bool Dividable();
	//check if this node contains specified tag node
	bool Contains(const CString& tagName);
	//helper for contains
	//check whether this sub-tree contains the specified tag node
	bool TreeContains(const CString& tagName);

	DOMNode* DiffBkChild(); // find the child whose background color is different from the current node

	CString toString();
private:
	void GetElementInfo();
	void GetAttrInfo();
	void GetVisualInfo();
	void GetCurrentStyleText();
	void InsertAttr(const CComBSTR& name, const CComVariant& value);	
	CString Variant2Str(const CComVariant& var);
	int StrLength(const CString &strText);  // calculate the text length in my way
	void AddChildren();
	void RootFirstVisit();
//corresponding IHTMLDOMNode
	CComQIPtr<IHTMLDOMNode> m_pDOMNode;
//tag name and value
	CString m_TagName;
	CString m_Value;

	int m_nTextLength; //length of the text in the tree
	int m_nLinkNum;
//type
	UINT m_nType;        //element or text
	UINT m_nAppearType;  //valid or text or virtual text or non valid
	UINT m_nLineType;    //inline or line break
//virtual info
	CString m_strBkColor;
	CString m_strForeColor;
	CString m_strFontFamily;
	CString m_strFontSize;
	CString m_strFontStyle;
	CString m_strFontWeight;
	long		m_lLeft;
	long		m_lTop;
	long		m_lWidth;
	long		m_lHeight;
	CString m_cssText;
	CString m_currentStyleText;
//attributes and children	
	std::map<CString,CString> m_attrs;	
public:
	std::vector<DOMNode*> m_Children;
private:
	static char* Block_Tags[];		
	static char* inline_tags[];
};
